home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / crystal / cvgo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-12  |  9.3 KB  |  381 lines

  1. /* cvgo.c
  2.  *    adventurer motion routine moveme()
  3.  *************************************************************************/
  4.  
  5. #include    <stdio.h>
  6. #include    "cvobj.h"
  7. #include    "cvocab.h"
  8. #include    "cvlocs.h"
  9. #include    "cvmisc.h"
  10. #include    "cvorcs.h"
  11. #include    "random.h"
  12.  
  13. extern struct cvobj *lastobj; /* cvmain.c */
  14.  
  15. static void
  16. wrongway(verb) int verb ;
  17. {    if ((verb == FIND) || (verb == INVENT)) {rspeak(59); return; }
  18.     if (verb <= ENTER) {rspeak(9); return; }
  19.     if ((verb == HOPE) 
  20.         || (verb == BANIS)
  21.         || (verb == MISFO)) {rspeak(42); return; }
  22.     rspeak(12);
  23.     return;
  24. }
  25.  
  26. static struct cvloc *
  27. leave(tr) register struct cvtrav *tr;
  28. {
  29.     if (tr->l <= 300) return &(cvloc[tr->l]) ;
  30.     if (tr->l <= 500)
  31.         switch (tr->l)
  32.     {
  33.     case 301: /* wrong magic word ! */
  34.         newloc = loc;
  35.         switch (SHELF->prop) {
  36.         case 0:
  37. shakeit:    if (loc - cvloc == SHELF->iloc || loc - cvloc == SHELF->iloc+1)
  38.                 rspeak(214);
  39.             else
  40.                 rspeak(162);
  41.             SHELF->prop ++ ;
  42.             return loc;
  43.         case 1:
  44.             if (PCT(25)) goto shakeit;
  45.             if (PCT(33)) {
  46.                 rspeak(42);
  47.                 return loc;
  48.             }
  49.             SHELF->prop++;
  50.             {    register struct cvobj *ob;
  51.                 register struct cvloc *shloc;
  52.                 shloc = &(cvloc[SHELF->iloc]);
  53.  
  54.                 /* dump everything off of shelf */
  55.                 for (ob = lastobj; ob != cvobj; ob--) {
  56.                     if (ob->conn1.where == shloc) move(ob,shloc+1);
  57.                 }
  58.                 move2(SHELF,shloc); /* shelf stays, though */
  59.                 if (!AT(SHELF)) {
  60.                     rspeak(162);
  61.                     return loc;
  62.                 }
  63.                 loc = shloc + 1;
  64.                 newloc = &(cvloc[25]);
  65.                 rspeak(163);
  66.                 return loc;
  67.             }
  68.         case 3: /* already destroyed */
  69.             rspeak(42);
  70.             return loc;
  71.         }
  72.     case 302: /* down a clean column */
  73.         loc = COLUMN->conn1.where;
  74.         if (COLUMN->prop == 0) {
  75.             COLUMN->prop = 1;
  76.             if (DAM->prop == 0) {
  77.                 loc = &(cvloc[getrick()]);
  78.             }
  79.         }
  80.         return loc;
  81.     case 303: /* out of maze .. activate grendl if carrying orb */
  82.         newloc = loc - 1;
  83.         SPIDER->prop = 0;
  84.         pspeak(SPIDER,2);
  85.         GRENDL->dseen = TRUE;
  86.         GRENDL->dloc = newloc;
  87.         return newloc;
  88.     case 305: /* jumped into bottomless fissure */
  89.         rspeak(224);
  90.         {    register struct cvobj *ob;
  91.             register int co;
  92.             co = 0;
  93.             for (ob = cvobj; ob->desc != NULL; ob++) {
  94.                 if (TOTING(ob)) {co++; destry(ob);}
  95.             }
  96.             if (RUG->prop == 1) RUG->prop = 0;
  97.             rspeak(co ? 134 : 133);
  98.         }
  99.         loc = newloc = oldlc2 = &(cvloc[62]);
  100.         return loc;
  101.     case 306: /* leave repository */
  102.         newloc = &(cvloc[146]);
  103.         if (MIRROR->prop == 1) {
  104.             MIRROR->prop = 0;
  105.             pspeak(MIRROR,2);
  106.             ME->dloc = loc;
  107.             ME->dseen = TRUE;
  108.         }
  109.         return loc;
  110.     default: bug(20);
  111.     }
  112.     rspeak((int)(tr->l - 500)) ;
  113.     return loc ;
  114. }
  115.  
  116. #define    SKIP    {ctrav = skip(ctrav); continue; }
  117. #define DOIT    { register struct cvloc *temp; temp = leave(ctrav) ;\
  118.                 if (ctrav->s) continue ; else return temp; }
  119. static struct cvtrav *
  120. skip(tr) register struct cvtrav *tr;
  121. {    while (tr->s) {++tr;} ;
  122.     return tr ;
  123. }
  124.  
  125. /* given the current location in parameter "where" and a verb in parameter
  126.  *    "verb", put the new location into the result.  The current loc is saved
  127.  *    in "oldloc" in case he wants to retreat.  The current "oldloc" is saved
  128.  *    in "oldlc2", in case he dies.  (If he does, "newloc" will be limbo, and
  129.  *    "oldloc" will be what killed him, so we need "oldlc2", which is the
  130.  *    last place he was safe.)
  131.  *
  132.  *    Each location (struct cvloc) has a travel array (struct cvtrav *travel)
  133.  *    of entries, each of which contains a word-number (or -1 to end the
  134.  *  array for this location) and maybe some other stuff.  If the location
  135.  *    and continue parts are both zero, subsequent entries are examined until
  136.  *    a useable one is found (this makes several motion words synonyms in the
  137.  *    location).  The continue flag makes for concatenated decisions, or for
  138.  *    messages then motions, all in one entry, without the need for fake
  139.  *    forced-motion locations. (e.g. AHHHHHHHHH...You are at the bottom with
  140.  *    a broken neck).
  141.  */
  142.  
  143. struct cvloc *
  144. moveme(where,verb) struct cvloc *where; int verb;
  145. {
  146.     register struct cvtrav *ctrav;
  147.     auto int rugrop;
  148.  
  149.     /* if he tries to use the compass, make sure this makes sense */
  150.     if ( (verb >= NORTH) && (verb <= NW))
  151.     {    if (where > (&(cvloc[30])) && !TOTING(COMPASS) )
  152.         {    rspeak(58); return where; } /* need compass */
  153.  
  154.         if (DARK)
  155.         {    rspeak(74) ; return where; } /* can't read compass */
  156.     }
  157.  
  158.     if (verb == WAIT) { return where; }
  159.  
  160.     if (verb == BACK)
  161.     {
  162.         /* look for a verb which goes from where to oldloc,
  163.             or if oldloc has forced motion, to oldlc2.  If one is found,
  164.             and the verb is not magic, and does not involve random motion,
  165.             he can go back. */
  166.  
  167.         register struct cvloc *backto;
  168.         register struct cvtrav *forceto ;
  169.         register int fword;
  170.  
  171.         backto = FORCED(oldloc) ? oldlc2 : oldloc ;
  172.         oldlc2 = oldloc ; oldloc = where ;
  173.  
  174.         if ( (backto == where) || PCT(5) ) 
  175.         {    rspeak(91); return where; }
  176.  
  177.         for (forceto = NULL,
  178.                 ctrav = where->travel; ctrav->word >= 0; ++ctrav)
  179.         {    if ((&(cvloc[ctrav->l])) == backto) {forceto = ctrav; break ; }
  180.             if (ctrav->l < 300)
  181.             {    register struct cvloc *through;
  182.                 through = &(cvloc[ctrav->l]) ;
  183.                 if (FORCED(through)
  184.                     && ((&(cvloc[through->travel->l])) == backto))
  185.                     forceto = ctrav ;
  186.             }
  187.         }
  188.  
  189.         if (forceto == NULL)
  190.         {    rspeak(140); /* you can't get there from here */
  191.             return where;
  192.         }
  193.  
  194.         fword = forceto->word ;
  195.         /* make him find his own magic words */
  196.         if ( (fword == HOPE)
  197.             || (fword == BANIS)
  198.             || (fword == MISFO) )
  199.         {    rspeak(91); return where; }
  200.  
  201.         /* don't go back through probabilities, or other conditions */
  202.         for (ctrav = where->travel; ctrav->word >= 0; ++ctrav)
  203.         {    if ( (ctrav->word == fword) && (ctrav->n))
  204.             { rspeak(91); return where; }
  205.         }
  206.         verb = fword ; /* change verb to the one that does it */
  207.     }
  208.  
  209.     oldlc2 = oldloc; oldloc = where;
  210.  
  211.     switch (verb)
  212.     {
  213.     case DOWN:    rugrop = 1 ; break ;
  214.     case UP:    rugrop = 2 ; break ;
  215.     case CLIMB:    rugrop = 3 ; break ;
  216.     default:    rugrop = 0 ; break ;
  217.     }
  218.  
  219.     /* find an entry with this motion verb */
  220.     for (ctrav = where->travel; ctrav->word >= 0; ++ctrav)
  221.     {    if ((ctrav->word == 1) || (ctrav->word == verb)) break ;
  222.     }
  223.  
  224.     if (ctrav->word < 0)
  225.     {    /* no such motion -- unless we can find a way to do it with the
  226.         rug or the rope */
  227.         if (rugrop) {
  228.             register int l, len;
  229.             register struct rtr *rtrp;
  230.             l = loc - cvloc;
  231.             len = 0;
  232.             for (rtrp = rtrav; rtrp->top > 0; rtrp++) {
  233.                 switch (rugrop) {
  234.                 case 3: /* he said "CLIMB" */
  235.                     if (rtrp->top == l) goto down;
  236.                     if (rtrp->bot == l) goto up;
  237.                     if (rtrp->mid == l) goto up;
  238.                 case 1: /* he said "DOWN" */
  239. down:
  240.                     if (rtrp->mid == l) {
  241.                         if (rtrp->bot) {
  242.                             l = rtrp->bot;
  243.                             len = 1;
  244.                         }
  245.                     } else if (rtrp->top == l) {
  246.                         if (rtrp->mid) {
  247.                             l = rtrp->mid;
  248.                             len = 1;
  249.                         } else {
  250.                             l = rtrp->bot;
  251.                             len = 2;
  252.                         }
  253.                     }
  254.                     break;
  255.                 case 2: /* he said "UP" */
  256. up:
  257.                     if (rtrp->mid == l) {
  258.                         l = rtrp->top;
  259.                         len = 1;
  260.                     } else if (rtrp->bot == l) {
  261.                         if (rtrp->mid) {
  262.                             l = rtrp->mid;
  263.                             len = 1;
  264.                         } else {
  265.                             l = rtrp->top;
  266.                             len = 2;
  267.                         }
  268.                     }
  269.                     break;
  270.                 } /* end switch */
  271.                 /* l = possible destination number */
  272.                 /* len = # of 60-foot rope segments needed */
  273.                 if (len) break;
  274.             } /* end for to find destination */
  275.             if (len) {
  276.                 newloc = &(cvloc[l]);
  277.                 if (RUG->prop == 1 && rugrop != 3) { /* flying? */
  278.                     if (rtrp->rug) {
  279.                         rspeak(199); /* flying where he shouldn't */
  280.                         move(RUG, &(cvloc[RUG->iloc]));
  281.                         oldlc2 = &(cvloc[rtrp->drop]);
  282.                         die();
  283.                     }
  284.                     return newloc;
  285.                 } /* end of flying */
  286.                 if (ROPE->conn1.where - cvloc == rtrp->top) {
  287.                     l = ROPE->prop;
  288.                     if (l % 2) goto L6345;
  289.                 }
  290.                 if (ROPE2->conn1.where - cvloc == rtrp->top) {
  291.                     l = ROPE2->prop;
  292.                     if (l == 3) goto L6345;
  293.                 }
  294.             /* check that you have the rope or carpet set up */
  295. L6340:            if (rtrp == rtrav) {
  296.                     if (PCT(20)) return loc;
  297.                     loc = DEAD;
  298.                     newloc = &(cvloc[24]);
  299.                     return newloc;
  300.                 }
  301.                 newloc = loc;
  302.                 if (RUG->prop == 0 && PCT(67)) rspeak(198);
  303.                 else rspeak(14);
  304.                 return newloc;
  305. L6345:
  306.                 switch (l) {
  307.                 case 3: /* 60 foot rope */
  308.                     if (len > 1) {
  309.                         rspeak(153);
  310.                         return loc;
  311.                     }
  312.                 case 1: /* 120 foot rope, uncut */
  313.                 case 7: /* 120 foot rope, spliced and tested */
  314. L6350:                    if (RUG->prop == 1) {
  315.                         newloc = loc;
  316.                         rspeak(117);
  317.                     }
  318.                     return newloc;
  319.                 case 5: /* 120 foot rope with a dangerous knot */
  320.                     if (RUG->prop == 1) {
  321.                         rspeak(117);
  322.                         return loc;
  323.                     }
  324.                     if (loc == &(cvloc[rtrp->bot]) ||
  325.                             newloc == &(cvloc[rtrp->bot])) {
  326.                         rspeak(208);
  327.                         ROPE->prop = 3; /* broken rope */
  328.                         EROPE->prop = 0;
  329.                         destry(EROPE2);
  330.                         move(ROPE2,&(cvloc[rtrp->drop]));
  331.                         ROPE2->prop = 2;
  332.                         oldlc2 = &(cvloc[rtrp->drop]);
  333.                         die();
  334.                         return newloc;
  335.                     }
  336.                     goto L6350;
  337.                 default:
  338.                     bug(55);
  339.                 } /* end of rope-state switch */
  340.             } else {
  341.                 newloc = loc;
  342.             }
  343.         } /* end of rug/rope possibilities */
  344.         wrongway(verb); return where;
  345.     }
  346.     
  347.     do
  348.     {
  349.         for (;!(ctrav->s) && !(ctrav->l) && !(ctrav->n);++ctrav) ;
  350.  
  351.         switch (ctrav->m)
  352.         {
  353.         case 0:
  354.             if ((ctrav->n) && !PCT(ctrav->n)) SKIP ;
  355.             DOIT ;
  356.         case IF_HAVE:
  357.             if (!TOTING(OBJ(ctrav->n))) SKIP ;
  358.             DOIT ;
  359.         case IF_NHAVE:
  360.             if (TOTING(OBJ(ctrav->n))) SKIP ;
  361.             DOIT ;
  362.         case IF_WITH:
  363.             if (!HERE(OBJ(ctrav->n))) SKIP ;
  364.             DOIT ;
  365.         case IF_NWITH:
  366.             if (HERE(OBJ(ctrav->n))) SKIP ;
  367.             DOIT ;
  368.         case IF_PROP:
  369.             if (OBJ(ctrav->n)->prop != ctrav->v) SKIP ;
  370.             DOIT ;
  371.         case IF_NPROP:
  372.             if (OBJ(ctrav->n)->prop == ctrav->v) SKIP ;
  373.             DOIT ;
  374.         }
  375.         bug(29) ;
  376.     } while ((++ctrav)->word >= 0) ;
  377.  
  378.     bug(25) ;
  379.     return where;
  380. }
  381.